/**
 * JFunny - A funny programming language
 * Copyright (C) 2013  fanguangping
 * Any problem email me: fguangping@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **/
package org.jfunny.core.ds;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.jfunny.core.dfa.DFA;
import org.jfunny.core.dfa.State;
import org.jfunny.core.parser.ParserFunny;
import org.jfunny.core.util.StringUtil;

/**
 * 语句模板映射
 * 
 * @author fanguangping
 * 
 */
public class StatementMapping {
	private String regexKey;
	private String regexValue;

	public List<Statement> keyTemplate;
	public List<Statement> valueTemplate;
	public State starter;

	public void constructDfa() {
		keyTemplate = getRegex("{" + regexKey + "}");
		valueTemplate = getRegex("{" + regexValue + "}");
		starter = DFA.getInstance().toDFA(keyTemplate);
	}

	public String getRegexKey() {
		return regexKey;
	}

	public void setRegexKey(String regexKey) {
		this.regexKey = regexKey;
	}

	public String getRegexValue() {
		return regexValue;
	}

	public void setRegexValue(String regexValue) {
		this.regexValue = regexValue;
	}

	private static List<Statement> getRegex(String template) {
		List<Statement> list = new LinkedList<Statement>();

		String before;
		String between;
		String after = template;
		while (after.contains("[")) {
			before = StringUtil.substringBefore(after, "[").trim() + "}";
			if (!"{}".equals(before)) {
				//list.add(ParserJfunny.parse(before));
				list.addAll(ParserFunny.parse(before).getChildren());
			}
			between = StringUtil.substringBetween(after, "[", "]").trim();
			after = StringUtil.substringAfter(after, "]").trim();

			if (after.startsWith("?")) {
				after = "{" + StringUtil.substringAfter(after, "?");
				Loop pattern = new Loop(Loop.ZERO_ONE);
				between = "{" + between + "}";
				pattern.setChildren((ArrayList<Statement>) ParserFunny.parse(between).getChildren());
				list.add(pattern);
			}
			else if (after.startsWith("*")) {
				after = "{" + StringUtil.substringAfter(after, "*");
				Loop pattern = new Loop(Loop.ZERO_MORE);
				between = "{" + between + "}";
				pattern.setChildren((ArrayList<Statement>) ParserFunny.parse(between).getChildren());
				list.add(pattern);
			}
			else if (after.startsWith("+")) {
				after = "{" + StringUtil.substringAfter(after, "+");
				Loop pattern = new Loop(Loop.ONE_MORE);
				between = "{" + between + "}";
				pattern.setChildren((ArrayList<Statement>) ParserFunny.parse(between).getChildren());
				list.add(pattern);
			}
			else {
				System.out.println("Error!");
			}

		}
		if (!"{}".equals(after)) {
			//list.add(ParserJfunny.parse(after));
			list.addAll(ParserFunny.parse(after).getChildren());
		}

		return list;
	}
}
